<?php

class ClassLoader {

	private $loadClass;
	
	public function __construct( $filename, $fixClassName, $type, $source ){
		if( is_file($filename) ){
			$readyClass = get_declared_classes();
			if( $fixClassName==null ){
				include_once $filename;
			}else if( $type==='Implements' || $type==='Extends' ){
				$buffer = file_get_contents($filename);
				if( strpos($buffer, $source) ){
					//fixed class name
					$buffer = str_replace('<?php','',$buffer);
					$buffer = str_replace('<? php','',$buffer);
					$buffer = str_replace('<?','',$buffer);
					$buffer = str_replace('?>','',$buffer);
					$buffer = 'class '.$fixClassName .' '.strtolower($type).' '. stristr($buffer, $source);
					//load it
					eval($buffer);
				}
			}
			$addClass = get_declared_classes();
			if( count($addClass)-count($readyClass)==1 ){
				$this->loadClass = $addClass[count($addClass)-1];
				return $this;
			}
		}
		return null;
	}
	
	/**
	 * Invoke the method name, this action must be taken before loading.
	 *
	 * @param String method name
	 * @return boolean
	 */
	public function callMethod( $method=null ){
		if( $this->loadClass!=null && $method!=null ){
			return call_user_method($method, $this->loadClass);
		}
		return false;
	}
	
	/**
	 * Chcek sub class
	 *
	 * @param String sub class name
	 * @return Class
	 */
	public function isSubClass( $subClass ){
		if( $subClass!=null && $this->loadClass!=null && is_subclass_of( $this->loadClass, $subClass) ){
			return $this;
		}
		return null;
	}
	
	/**
	 * Load the class and fix it
	 *
	 * @param String filename
	 * @param String fix class name
	 * @param String implements interface
	 * @return Class
	 */
	public static function loadImplements( $filename, $fixClassName=null, $interface ){
		return new ClassLoader($filename, $fixClassName, 'Implements', $interface);
	}
	
	/**
	 * Load the class and fix it
	 *
	 * @param String filename
	 * @param String fix class name
	 * @param String extends class name
	 * @return Class
	 */
	public static function loadExtends( $filename, $fixClassName=null, $class ){
		return new ClassLoader($filename, $fixClassName, 'Extends', $class);
	}
	
	/**
	 * Load the class and fix it
	 *
	 * @param String filename
	 * @param String fix class name
	 * @return Class
	 */
	public static function load( $filename, $fixClassName=null ){
		return new ClassLoader($filename, $fixClassName, null);
	}
	
}

?>